/**
 * Created by DukeCrushIt on 2015/7/30.
 */
//module dukeutil{
    class GravitySystem {
        public gravity:number = 0.98;
        private items:GravityItem[] = [];
        private itemMap:Object = {};
        private frameItem:FrameItem;
        public name:string;
        public exceptionArea:egret.Rectangle;
        public constructor(){
            //super();
            this.name = "gravitysystem";
            this.frameItem = new FrameItem();
            this.frameItem.callFun = this.update;
            this.frameItem.callObj = this;
            FrameMgr.getInstance().addControll(this.frameItem);
        }

        public addItem(item:GravityItem){
            if( this.items.indexOf(item) == -1 ){
                this.items.push(item);
                this.itemMap[item.displayObject.name] = item;
            }
        }
        public removeItemByName(name:string){
            var item:GravityItem = this.itemMap[name];
            if( item){
                var index = this.items.indexOf(item);
                item.displayObject.y = item.targetY;
                if( index != -1){
                    this.items.splice(index,1);
                }
                GravitySystem.reclaim(item);
                delete  this.itemMap[name];
            }
        }
        public contains(name:string):boolean{
            return this.itemMap[name] != undefined;
        }
        private spareTime:number = 10;
        private update(delata:number){
            var startTime = egret.getTimer();
            var gap:number;
            var len:number = this.items.length;
            var idx:number;
            var item:GravityItem;
            var displayObject:egret.DisplayObject;
            for(idx = len-1; idx >= 0; idx--){
                item = this.items[idx];
                displayObject = item.displayObject;
                if( item.phase == 0){
                    displayObject.x+=item.currentSpeedX;
                    item.currentSpeedY += this.gravity;
                    displayObject.y += item.currentSpeedY;
                    if( item.doublePhase && displayObject.y >= item.targetY){
                            item.phase = 1;
                            item.currentSpeedX = item.currentSpeedX*0.8;
                    }else if( !item.doublePhase && (item.currentSpeedY < 1 && item.currentSpeedY > -1)){
                        delete this.itemMap[item.displayObject.name];
                        this.items.splice(idx,1);
                        if( item.overCall != null && item.overCallObj != null)
                            item.overCall.call(item.overCallObj);
                        item.reset();
                        GravitySystem.reclaim(item);
                    }
                }else{
                    item.step++;
                    item.currentSpeedX = item.currentSpeedX*0.9;
                    displayObject.x+=item.currentSpeedX;

                    if( item.currentSpeedX > 0){
                        displayObject.rotation+=2;
                    }else{
                        displayObject.rotation-=2;
                    }
                    if( item.step >= 30){
                        delete this.itemMap[item.displayObject.name];
                        this.items.splice(idx,1);
                        if( item.overCall != null && item.overCallObj != null)
                            item.overCall.call(item.overCallObj);
                        item.reset();
                        GravitySystem.reclaim(item);
                    }
                }
                if( displayObject.x <= 0 || displayObject.x >= GameConst.StageW){
                    item.currentSpeedX = -item.currentSpeedX;
                }
                if(this.exceptionArea && this.exceptionArea.contains(displayObject.x,displayObject.y)){
                    delete this.itemMap[item.displayObject.name];
                    this.items.splice(idx,1);
                    if( item.overCall != null && item.overCallObj != null)
                        item.overCall.call(item.overCallObj);
                    item.reset();
                    GravitySystem.reclaim(item);
                }
                gap = egret.getTimer() - startTime;
                if( gap >= this.spareTime)
                    break;
            }
        }

        public removeAllHairItem(){
            var idx:number;
            var item:GravityItem;
            var displayObject:egret.DisplayObject;
            var len = this.items.length;
            for(idx = len-1; idx >= 0; idx--) {
                item = this.items[idx];
                displayObject = item.displayObject;
                if( displayObject instanceof Hair){
                    if( item.overCall != null && item.overCallObj != null)
                        item.overCall.call(item.overCallObj);
                    this.items.splice(idx,1);
                    item.reset();
                    GravitySystem.reclaim(item);
                }
            }
        }

        private static _itemCache:GravityItem[] = [];
        public static produce():GravityItem{
            if( GravitySystem._itemCache.length != 0)
                return GravitySystem._itemCache.pop();
            return new GravityItem();
        }
        public static reclaim(item:GravityItem){
            if( GravitySystem._itemCache.indexOf(item) == -1)
                GravitySystem._itemCache.push(item);
        }

        private static _instance:GravitySystem;
        public static getInstance():GravitySystem{
            if( GravitySystem._instance == null )
                GravitySystem._instance = new GravitySystem();
            return GravitySystem._instance;
        }
    }
//}